class Base64 {
  base64Decode(input: string) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
    const str = String(input).replace(/-/g, '+').replace(/_/g, '/').replace(/[=]+$/, '')

    if (str.length % 4 === 1) {
      throw new Error('The string to be decoded is not correctly encoded')
    }

    let output = ''

    for (
      // initialize result and counters
      // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>
      let bc = 0, bs = 0, buffer, idx = 0;
      // get next character
      // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
      (buffer = str.charAt(idx++));
      // character found in table? initialize bit storage and add its ascii value;
      ~buffer &&
      // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
      // biome-ignore lint/style/noCommaOperator: <explanation>
      ((bs = bc % 4 ? bs * 64 + buffer : buffer),
      // and if not first of each 4 characters,
      // convert the first 8 bits to one ascii character
      bc++ % 4)
        ? // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
          (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6))))
        : 0
    ) {
      // try to find character in table (0-63, not found => -1)
      buffer = chars.indexOf(buffer)
    }

    output = decodeURIComponent(
      output
        .split('')
        // biome-ignore lint/style/useTemplate: <explanation>
        .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
        .join('')
    )

    return output
  }
}

export default new Base64()
